#include "touchscreen.h"
#include <stdio.h>
#include <linux/uinput.h>
#include <unistd.h>
#include <fcntl.h>
#include <string.h>

TouchScreen::TouchScreen()
{
    uinp_fd=-1;

    if (setup_uinput_device() < 0)
    {
        printf("Unable to find uinput device\n");
        return ;
    }
}
TouchScreen::~TouchScreen()
{
    if(uinp_fd>=0){
    /* Destroy the input device */
    ioctl(uinp_fd, UI_DEV_DESTROY);
    /* Close the UINPUT device */
    close(uinp_fd);
    }
}

/* Setup the uinput device */
int TouchScreen:: setup_uinput_device()
{
    struct uinput_user_dev uinp;// uInput device structure

// Temporary variable
int i=0;
// Open the input device
uinp_fd = open("/dev/uinput", O_WRONLY | O_NDELAY);
if (uinp_fd == NULL)
{
    //Dashboard January 2007 Issue
printf("Unable to open /dev/uinput\n");
return -1;
}
memset(&uinp,0,sizeof(uinp));// Intialize the uInput device to NULL
strncpy(uinp.name, "PolyVision Touch Screen", UINPUT_MAX_NAME_SIZE);
uinp.id.version = 4;
uinp.id.bustype = BUS_USB;
// Setup the uinput device
ioctl(uinp_fd, UI_SET_EVBIT, EV_KEY);
ioctl(uinp_fd, UI_SET_EVBIT, EV_REL);
ioctl(uinp_fd, UI_SET_RELBIT, REL_X);
ioctl(uinp_fd, UI_SET_RELBIT, REL_Y);
for (i=0; i < 256; i++) {
ioctl(uinp_fd, UI_SET_KEYBIT, i);
}
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MOUSE);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_TOUCH);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MOUSE);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_LEFT);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_MIDDLE);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_RIGHT);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_FORWARD);
ioctl(uinp_fd, UI_SET_KEYBIT, BTN_BACK);
/* Create input device into input sub-system */
write(uinp_fd, &uinp, sizeof(uinp));
if (ioctl(uinp_fd, UI_DEV_CREATE))
{
printf("Unable to create UINPUT device.");
return -1;
}
return 1;
}
void TouchScreen::send_move_events(int x, int y)
{
    struct input_event event; // Input device structure
    if(uinp_fd<0) return;
    // Move pointer to (x,y) location
    memset(&event, 0, sizeof(event));
    gettimeofday(&event.time, NULL);
    event.type = EV_REL;
    event.code = REL_X;
    event.value = x;//100;
    write(uinp_fd, &event, sizeof(event));
    event.type = EV_REL;
    event.code = REL_Y;
    event.value = y;//100;
    write(uinp_fd, &event, sizeof(event));
    event.type = EV_SYN;
    event.code = SYN_REPORT;
    event.value = 0;
    write(uinp_fd, &event, sizeof(event));
}

void TouchScreen::send_click_events(int x,int y )
{
    struct input_event event; // Input device structure
    if(uinp_fd<0) return;
// Move pointer to (x,y) location
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_REL;
event.code = REL_X;
event.value = x;//100;
write(uinp_fd, &event, sizeof(event));
event.type = EV_REL;
event.code = REL_Y;
event.value = y;//100;
write(uinp_fd, &event, sizeof(event));
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(uinp_fd, &event, sizeof(event));
// Report BUTTON CLICK - PRESS event
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_KEY;
event.code = BTN_LEFT;
event.value = 1;
write(uinp_fd, &event, sizeof(event));
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(uinp_fd, &event, sizeof(event));
// Report BUTTON CLICK - RELEASE event
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_KEY;
event.code = BTN_LEFT;
event.value = 0;
write(uinp_fd, &event, sizeof(event));
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(uinp_fd, &event, sizeof(event));
}
void TouchScreen::send_a_button(int code)
{
    struct input_event event; // Input device structure
    if(uinp_fd<0) return;
// Report BUTTON CLICK - PRESS event
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_KEY;
event.code = code;//KEY_A;
event.value = 1;
write(uinp_fd, &event, sizeof(event));
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(uinp_fd, &event, sizeof(event));
// Report BUTTON CLICK - RELEASE event
memset(&event, 0, sizeof(event));
gettimeofday(&event.time, NULL);
event.type = EV_KEY;
event.code = code;//KEY_A;
event.value = 0;
write(uinp_fd, &event, sizeof(event));
event.type = EV_SYN;
event.code = SYN_REPORT;
event.value = 0;
write(uinp_fd, &event, sizeof(event));
}
